home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / bash / bash_108 / bash-108.zoo / src / shell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-12  |  35.9 KB  |  1,500 lines

  1. /* shell.c -- GNU's idea of the POSIX shell specification.
  2.  
  3.    This file is part of Bash, the Bourne Again SHell.  Bash is free
  4.    software; no one can prevent you from reading the source code, or
  5.    giving it to someone else.  This file is copyrighted under the GNU
  6.    General Public License, which can be found in the file called
  7.    COPYING.
  8.  
  9.    Copyright (C) 1988, 1991 Free Software Foundation, Inc.
  10.  
  11.    This file is part of GNU Bash.
  12.  
  13.    Bash is distributed in the hope that it will be useful, but WITHOUT
  14.    ANY WARRANTY.  No author or distributor accepts responsibility to
  15.    anyone for the consequences of using it or for whether it serves
  16.    any particular purpose or works at all, unless he says so in
  17.    writing.  Refer to the GNU Emacs General Public License for full
  18.    details.
  19.  
  20.    Everyone is granted permission to copy, modify and redistribute
  21.    Bash, but only under the conditions described in the GNU General
  22.    Public License.  A copy of this license is supposed to have been
  23.    given to you along with GNU Emacs so you can know your rights and
  24.    responsibilities.  It should be in a file named COPYING.
  25.  
  26.    Among other things, the copyright notice and this notice must be
  27.    preserved on all copies.
  28.  
  29.   Birthdate:
  30.   Sunday, January 10th, 1988.
  31.   Initial author: Brian Fox
  32. */
  33.  
  34. #include <stdio.h>
  35. #include <signal.h>
  36. #include <errno.h>
  37. #include <sys/types.h>
  38. #if !defined (sony)
  39. #include <fcntl.h>
  40. #endif /* sony */
  41.  
  42. #include <sys/file.h>
  43. #include "posixstat.h"
  44. #include <pwd.h>
  45.  
  46. #if defined (HAVE_VPRINTF)
  47. #include <varargs.h>
  48. #endif
  49.  
  50. #include "shell.h"
  51. #include "flags.h"
  52.  
  53. #if defined (JOB_CONTROL)
  54. #include "jobs.h"
  55. #endif /* JOB_CONTROL */
  56.  
  57. #if defined (USG) && !defined (isc386)
  58. struct passwd *getpwuid ();
  59. #endif
  60.  
  61. extern char *dist_version;
  62. extern int build_version;
  63.  
  64. extern int yydebug;
  65.  
  66. /* Non-zero means that this shell has already been run; i.e. you should
  67.    call shell_reinitialize () if you need to start afresh. */
  68. int shell_initialized = 0;
  69.  
  70. /* The current maintainer of the shell.  You change this in the
  71.    Makefile. */
  72. #if !defined (MAINTAINER)
  73. #define MAINTAINER "deliberately-anonymous"
  74. #endif
  75.  
  76. char *the_current_maintainer = MAINTAINER;
  77.  
  78. #ifndef PPROMPT
  79. #define PPROMPT "bash\\$ "
  80. #endif
  81. char *primary_prompt = PPROMPT;
  82.  
  83. #ifndef SPROMPT
  84. #define SPROMPT "bash> "
  85. #endif
  86. char *secondary_prompt = SPROMPT;
  87.  
  88. COMMAND *global_command = (COMMAND *)NULL;
  89.  
  90. /* Non-zero after SIGINT. */
  91. int interrupt_state = 0;
  92.  
  93. /* The current user's name. */
  94. char *current_user_name = (char *)NULL;
  95.  
  96. /* The current host's name. */
  97. char *current_host_name = (char *)NULL;
  98.  
  99. /* Non-zero means that this shell is a login shell.
  100.    Specifically:
  101.    0 = not login shell.
  102.    1 = login shell from getty (or equivalent fake out)
  103.   -1 = login shell from "-login" flag.
  104.   -2 = both from getty, and from flag.
  105.  */
  106. int login_shell = 0;
  107.  
  108. /* Non-zero means that at this moment, the shell is interactive. */
  109. int interactive = 0;
  110.  
  111. /* Non-zero means that the shell was started as an interactive shell. */
  112. int interactive_shell = 1;
  113.  
  114. /* Non-zero means to remember lines typed to the shell on the history
  115.    list.  This is different than the user-controlled behaviour; this
  116.    becomes zero when we read lines from a file, for example. */
  117. int remember_on_history = 1;
  118.  
  119. /* Non-zero means this shell is restricted. */
  120. int restricted = 0;
  121.  
  122. /* Special debugging helper. */
  123. int debugging_login_shell = 0;
  124.  
  125. /* The environment that the shell passes to other commands. */
  126. char **shell_environment;
  127.  
  128. /* Non-zero when we are executing a top-level command. */
  129. int executing = 0;
  130.  
  131. /* The number of commands executed so far. */
  132. int current_command_number = 1;
  133.  
  134. /* The environment at the top-level REP loop.  We use this in the case of
  135.    error return. */
  136. /**
  137.  ** (sjk)++ catch is defined in setjmp.h on the Atari ST
  138.  **/
  139. #if !defined(atarist)
  140. jmp_buf top_level, catch;
  141. #else 
  142. jmp_buf top_level;
  143. #endif
  144.  
  145.  
  146. /* Non-zero is the recursion depth for commands. */
  147. int indirection_level = 0;
  148.  
  149. /* The number of times BASH has been executed.  This is set
  150.    by initialize_variables () in variables.c. */
  151. int shell_level = 0;
  152.  
  153. /* The name of this shell, as taken from argv[0]. */
  154. char *shell_name = (char *)NULL;
  155.  
  156. /* time in seconds when the shell was started */
  157. time_t shell_start_time;
  158.  
  159. /* The name of the .(shell)rc file. */
  160. char *bashrc_file = "~/.bashrc";
  161.  
  162. /* Non-zero means to act more like the Bourne shell on startup. */
  163. int act_like_sh = 0;
  164.  
  165. /* Values for the long-winded argument names. */
  166. int debugging = 0;        /* Do debugging things. */
  167. int no_rc = 0;            /* Don't execute ~/.bashrc */
  168. int no_profile = 0;        /* Don't execute .profile */
  169. int do_version = 0;        /* Display interesting version info. */
  170. int quiet = 0;            /* Be quiet when starting up. */
  171. int make_login_shell = 0;    /* Make this shell be a `-bash' shell. */
  172. int no_line_editing = 0;    /* Don't do fancy line editing. */
  173. int no_brace_expansion = 0;    /* Non-zero means no foo{a,b} -> fooa fooa. */
  174.  
  175. /* Some long-winded argument names.  These are obviously new. */
  176. #define Int 1
  177. #define Charp 2
  178. struct {
  179.   char *name;
  180.   int *value;
  181.   int type;
  182. } long_args[] = {
  183.   { "debug", &debugging, Int },
  184.   { "norc", &no_rc, Int },
  185.   { "noprofile", &no_profile, Int },
  186.   { "rcfile", (int *)&bashrc_file, Charp},
  187.   { "version", &do_version, Int},
  188.   { "quiet", &quiet, Int},
  189.   { "login", &make_login_shell, Int},
  190.   { "nolineediting", &no_line_editing, Int},
  191.   { "nobraceexpansion", &no_brace_expansion, Int},
  192.   { (char *)NULL, (int *)0x0, 0 }
  193. };
  194.  
  195. /* The number of lines that Bash has added to this history session. */
  196. int history_lines_this_session = 0;
  197.  
  198. /* The number of lines that Bash has read from the history file. */
  199. int history_lines_in_file = 0;
  200.  
  201. /* These are extern so execute_simple_command can set them, and then
  202.    longjmp back to main to execute a shell script, instead of calling
  203.    main () again and resulting in indefinite, possibly fatal, stack
  204.    growth. */
  205. jmp_buf subshell_top_level;
  206. int subshell_argc;
  207. char **subshell_argv;
  208. char **subshell_envp;
  209.  
  210. main (argc, argv, env)
  211.      int argc;
  212.      char **argv, **env;
  213. {
  214.   extern int last_command_exit_value;
  215.   extern char *base_pathname ();
  216.   int i, arg_index, locally_skip_execution;
  217.   int top_level_arg_index, read_from_stdin;
  218.   FILE *default_input;
  219.   char *local_pending_command = (char *)NULL;
  220. #if defined (JOB_CONTROL)
  221.   extern int job_control;
  222. #endif /* JOB_CONTROL */
  223.  
  224. #if defined (AUX)
  225. #include <compat.h>
  226.   set42sig ();
  227.   setcompat (getcompat() | COMPAT_BSDGROUPS | COMPAT_BSDSIGNALS |
  228.          COMPAT_BSDTTY | COMPAT_EXEC | COMPAT_SYSCALLS);
  229. #endif /* AUX */
  230.  
  231. /**
  232.  ** (sjk)++ Set the default unixmode as we cannot assume that the variable 
  233.  **         is set upon entering the shell.
  234.  **/
  235. #if defined(atarist)
  236.  if (!getenv("UNIXMODE")) _set_unixmode("/.,rCLAHdb");
  237.     else _set_unixmode(getenv("UNIXMODE"));
  238. #endif
  239.  
  240.  
  241.   /* Wait forever if we are debugging a login shell. */
  242.   while (debugging_login_shell);
  243.  
  244.   if (setjmp (subshell_top_level))
  245.     {
  246.       argc = subshell_argc;
  247.       argv = subshell_argv;
  248.       env = subshell_envp;
  249.     }
  250.  
  251.   /* Initialize local variables for all `invocations' of main (). */
  252.   arg_index = 1;
  253.   local_pending_command = (char *)NULL;
  254.   locally_skip_execution = 0;
  255.   read_from_stdin = 0;
  256.   default_input = stdin;
  257.  
  258.   /* Fix for the `infinite process creation' bug when running shell scripts
  259.      from startup files on System V. */
  260.   login_shell = make_login_shell = 0;
  261.  
  262.   /* If this shell has already been run, then reinitialize it to a
  263.      vanilla state. */
  264.   if (shell_initialized || shell_name)
  265.     {
  266.       /* Make sure that we do not infinitely recurse as a login shell. */
  267.       if (*shell_name == '-')
  268.     shell_name++;
  269.  
  270.       shell_reinitialize ();
  271.       if (setjmp (top_level))
  272.     exit (2);
  273.     }
  274.  
  275.   /* Here's a hack.  If the name of this shell is "sh", then don't do
  276.      any startup files; just try to be more like /bin/sh. */
  277.   {
  278.     char *tshell_name = base_pathname (argv[0]);
  279.  
  280.     if (*tshell_name == '-')
  281.       tshell_name++;
  282.  
  283.     if (strcmp (tshell_name, "sh") == 0)
  284.       act_like_sh++;
  285.   }
  286.  
  287.   yydebug = 0;
  288.  
  289.   shell_environment = env;
  290.   shell_name = argv[0];
  291.   dollar_vars[0] = savestring (shell_name);
  292.  
  293.   if (*shell_name == '-')
  294.     {
  295.       shell_name++;
  296.       login_shell++;
  297.     }
  298.  
  299. #ifdef JOB_CONTROL
  300.   if (act_like_sh)
  301.     job_control = 0;
  302. #endif
  303.  
  304.   shell_start_time = NOW;    /* NOW now defined in general.h */
  305.  
  306.   /* A program may start an interactive shell with
  307.      "execl ("/bin/bash", "-", NULL)".  If so, default the name of this
  308.      shell to our name. */
  309.   if (!shell_name || !*shell_name || (strcmp (shell_name, "-") == 0))
  310.     shell_name = "bash";
  311.      
  312.   /* Parse argument flags from the input line. */
  313.  
  314.   /* Find full word arguments first. */
  315.   while ((arg_index != argc) && *(argv[arg_index]) == '-')
  316.     {
  317.       for (i = 0; long_args[i].name; i++)
  318.     {
  319.       if (strcmp (&(argv[arg_index][1]), long_args[i].name) == 0)
  320.         {
  321.           if (long_args[i].type == Int)
  322.         *(long_args[i].value) = 1;
  323.           else
  324.         {
  325.           if (!argv[++arg_index])
  326.             {
  327.               report_error ("%s: Flag `%s' expected an argument",
  328.                     shell_name, long_args[i].name);
  329.               exit (1);
  330.             }
  331.           else
  332.             *long_args[i].value = (int)argv[arg_index];
  333.         }
  334.           goto next_arg;
  335.         }
  336.     }
  337.       break;            /* No such argument.  Maybe flag arg. */
  338.     next_arg:
  339.       arg_index++;
  340.     }
  341.  
  342.   /* If user supplied the "-login" flag, then set and invert LOGIN_SHELL. */
  343.   if (make_login_shell)
  344.     login_shell = -++login_shell;
  345.  
  346.   /* All done with full word args; do standard shell arg parsing.*/
  347.   while (arg_index != argc && argv[arg_index] &&
  348.      (*(argv[arg_index]) == '-' || (*argv[arg_index] == '+')))
  349.     {
  350.       /* There are flag arguments, so parse them. */
  351.       int arg_character;
  352.       int on_or_off = (*argv[arg_index]);
  353.       int  i = 1;
  354.       char *o_option;
  355.       int next_arg = arg_index + 1;
  356.  
  357.       /* A single `-' signals the end of options.  From the 4.3 BSD sh.
  358.      An option `--' means the same thing; this is the standard
  359.      getopt () meaning. */
  360.       if (((argv[arg_index][0] == '-') && (argv[arg_index][1] == '\0')) ||
  361.       (strcmp (argv[arg_index], "--") == 0))
  362.     {
  363.       arg_index++;
  364.       goto after_flags;
  365.     }
  366.  
  367.       while (arg_character = (argv[arg_index])[i++])
  368.     {
  369.       switch (arg_character)
  370.         {
  371.         case 'c':
  372.           /* The next arg is a command to execute, and the following args
  373.          are $1 .. $n respectively. */
  374.         local_pending_command = argv[++arg_index];
  375.         if (!local_pending_command)
  376.           {
  377.             report_error ("`%cc' requires an argument", on_or_off);
  378.             exit (1);
  379.           }
  380.         arg_index++;
  381.         goto after_flags;
  382.  
  383.         case 's':
  384.         read_from_stdin = 1;
  385.         break;
  386.  
  387.         case 'o':
  388.         o_option = argv[next_arg++];
  389.         if (!o_option)
  390.           {
  391.             report_error ("`%co' requires an argument", on_or_off);
  392.             exit (1);
  393.           }
  394.  
  395.         if (set_minus_o_option (on_or_off, o_option) != EXECUTION_SUCCESS)
  396.           exit (1);
  397.         break;
  398.  
  399.         default:
  400.           if (change_flag_char (arg_character, on_or_off) == FLAG_ERROR)
  401.         {
  402.           report_error ("%c%c: bad option", on_or_off, arg_character);
  403.           exit (1);
  404.         }
  405.  
  406.         }
  407.     }
  408.       /* Can't do just a simple increment anymore -- what about
  409.      "bash -abouo emacs ignoreeof -hO"? */
  410.       arg_index = next_arg;
  411.     }
  412.  
  413.  after_flags:
  414.  
  415.   /* First, let the outside world know about our interactive status.
  416.      A shell is interactive if the `-i' flag was given, or if all of
  417.      the following conditions are met:
  418.     no -c command
  419.     no arguments remaining or the -s flag given
  420.     standard input is a terminal
  421.     standard output is a terminal
  422.      Refer to Posix.2, the description of the `sh' utility. */
  423.  
  424.   if (forced_interactive ||        /* -i flag */
  425.       (!local_pending_command &&    /* -c command */
  426.        ((arg_index == argc) ||        /* No remaining args or... */
  427.     read_from_stdin) &&        /* -s flag with args */
  428.        isatty (fileno (stdin)) &&    /* Input is a terminal and */
  429.        isatty (fileno (stdout))))    /* output is a terminal. */
  430.     interactive = 1;
  431.   else
  432.     {
  433.       extern int history_expansion;
  434.  
  435.       history_expansion = remember_on_history = 0;
  436.       interactive = 0;
  437. #ifdef JOB_CONTROL
  438.       job_control = 0;
  439. #endif
  440.     }
  441.  
  442. #define CLOSE_FDS_AT_LOGIN
  443.  
  444. #if defined (CLOSE_FDS_AT_LOGIN)
  445.   /*
  446.    * Some systems have the bad habit of starting login shells with lots of open
  447.    * file descriptors.  For instance, most systems that have picked up the
  448.    * pre-4.0 Sun YP code leave a file descriptor open each time you call one
  449.    * of the getpw* functions, and it's set to be open across execs.  That
  450.    * means one for login, one for xterm, one for shelltool, etc.
  451.    */
  452.   if (login_shell && interactive)
  453.     {
  454.       register int i;
  455.       for (i = 3; i < 20; i++)
  456.     close (i);
  457.     }
  458. #endif /* CLOSE_FDS_AT_LOGIN */
  459.  
  460.   /* From here on in, the shell must be a normal functioning shell.
  461.      Variables from the environment are expected to be set, etc. */
  462.   shell_initialize ();
  463.  
  464.   if (interactive)
  465.     {
  466.       char *term = (char *)getenv ("TERM");
  467.       if (term && (strcmp (term, "emacs") == 0))
  468.     no_line_editing = 1;
  469.     }
  470.  
  471.   top_level_arg_index = arg_index;
  472.  
  473.   if (!quiet && do_version)
  474.     show_shell_version ();
  475.  
  476.   /* Give this shell a place to longjmp to before executing the
  477.      startup files.  This allows users to press C-c to abort the
  478.      lengthy startup. */
  479.   if (setjmp (top_level))
  480.     {
  481.       if (!interactive)
  482.     exit (2);
  483.       else
  484.     locally_skip_execution++;
  485.     }
  486.  
  487.   arg_index = top_level_arg_index;
  488.  
  489.   /* Execute the start-up scripts. */
  490.  
  491.   if (!interactive)
  492.     {
  493.       makunbound ("PS1", shell_variables);
  494.       makunbound ("PS2", shell_variables);
  495.       interactive_shell = 0;
  496.     }
  497.   else
  498.     {
  499.       change_flag_char ('i', FLAG_ON);
  500.     }
  501.  
  502.   if (!locally_skip_execution)
  503.     {
  504.       if (login_shell)
  505.     maybe_execute_file ("/etc/profile");
  506.  
  507.       if (login_shell && !no_profile)
  508.     {
  509.       /* If we are doing the .bash_profile, then don't do the .bashrc. */
  510.       no_rc++;
  511.  
  512.       if (act_like_sh)
  513.         maybe_execute_file ("~/.profile");
  514.       else
  515.         {
  516.           if (maybe_execute_file ("~/.bash_profile") == 0)
  517.         if (maybe_execute_file ("~/.bash_login") == 0)
  518.           maybe_execute_file ("~/.profile");
  519.         }
  520.  
  521.     /* I turn on the restrictions afterwards because it is explictly
  522.        stated in the POSIX spec that PATH cannot be set in a restricted
  523.        shell, except in .profile. */
  524.       if (*++(argv[0]) == 'r')
  525.         {
  526.           set_var_read_only ("PATH");
  527.           set_var_read_only ("SHELL");
  528.           restricted++;
  529.         }
  530.     }
  531.  
  532.       /* Execute ~/.bashrc for most shells.  Never execute it if
  533.      ACT_LIKE_SH is set, or if NO_RC is set.
  534.  
  535.      If the executable file "/usr/gnu/src/bash/foo" contains:
  536.  
  537.        #!/usr/gnu/bin/bash
  538.        echo hello
  539.  
  540.      then:
  541.  
  542.      COMMAND        EXECUTE BASHRC
  543.      --------------------------------
  544.      bash -c foo        NO
  545.      bash foo        NO
  546.      foo            NO
  547.      rsh machine ls        YES (for rsh, which calls `bash -c')
  548.      rsh machine foo    YES (for shell started by rsh) NO (for foo!)
  549.      echo ls | bash        NO
  550.      login            YES
  551.      bash            YES
  552.       */
  553.       if (!act_like_sh && !no_rc &&
  554.       (interactive || (!isatty (fileno (stdin)) &&
  555.                local_pending_command)))
  556.     maybe_execute_file (bashrc_file);
  557.  
  558.       /* Try a TMB suggestion.  If running a script, then execute the
  559.      file mentioned in the ENV variable. */
  560.       if (!interactive)
  561.     {
  562.       char *env_file = (char *)getenv ("ENV");
  563.       if (env_file && *env_file)
  564.         {
  565.           WORD_LIST *list, *expand_string_unsplit ();
  566.           char *expanded_file_name, *string_list ();
  567.  
  568.           list = expand_string_unsplit (env_file, 1);
  569.           if (list)
  570.         {
  571.           expanded_file_name = string_list (list);
  572.           dispose_words (list);
  573.           if (expanded_file_name && *expanded_file_name)
  574.             maybe_execute_file (expanded_file_name);
  575.           free (expanded_file_name);
  576.         }
  577.         }
  578.     }
  579.  
  580.       if (local_pending_command)
  581.     {
  582.       /* Bind remaining args to $1 ... $n */
  583.       WORD_LIST *args = (WORD_LIST *)NULL;
  584.       while (arg_index != argc)
  585.         args = make_word_list (make_word (argv[arg_index++]), args);
  586.       args = (WORD_LIST *)reverse_list (args);
  587.       remember_args (args, 1);
  588.       dispose_words (args);
  589.  
  590.       with_input_from_string (local_pending_command, "-c");
  591.       goto read_and_execute;
  592.     }
  593.     }
  594.  
  595.   /* Do the things that should be done only for interactive shells. */
  596.   if (interactive)
  597.     {
  598. /**
  599.  ** (sjk)++ Remove all host/mail code on the Atari ST
  600.  **/
  601. #if !defined(atarist)
  602.       /* Set up for checking for presence of mail. */
  603. #if defined (USG)
  604.       /* Under System V, we can only tell if you have mail if the
  605.      modification date has changed.  So remember the current
  606.      modification dates. */
  607.       remember_mail_dates ();
  608. #else
  609.       /* Under 4.x, you have mail if there is something in your inbox.
  610.      I set the remembered mail dates to 1900.  */
  611.       reset_mail_files ();
  612. #endif /* USG */
  613.  
  614.       /* If this was a login shell, then assume that /bin/login has already
  615.      taken care of informing the user that they have new mail.  Otherwise,
  616.      we want to check right away. */
  617.       if (login_shell == 1)
  618.     {
  619. #if !defined (USG)
  620.       remember_mail_dates ();
  621. #endif
  622.     }
  623.  
  624.       reset_mail_timer ();
  625. #endif 
  626.  
  627.       change_flag_char ('i', FLAG_ON);
  628.       
  629.       /* Initialize the interactive history stuff. */
  630.       if (!shell_initialized)
  631.     {
  632.       char *hf;
  633.  
  634.       /* Truncate history file for interactive shells which desire it.
  635.          Note that the history file is automatically truncated to the
  636.          size of HISTSIZE if the user does not explicitly set the size
  637.          differently. */
  638.       set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
  639.       stupidly_hack_special_variables ("HISTFILESIZE");
  640.  
  641.       /* Read the history in HISTFILE into the history list. */
  642.       hf = get_string_value ("HISTFILE");
  643.  
  644.       if (hf)
  645.         {
  646.           struct stat buf;
  647.  
  648.           if (stat (hf, &buf) == 0)
  649.         {
  650.           void using_history ();
  651.  
  652.           read_history (hf);
  653.           using_history ();
  654.           history_lines_in_file = where_history ();
  655.         }
  656.         }
  657.     }
  658.     }
  659.  
  660.   /* Get possible input filename. */
  661.   if ((arg_index != argc) && !read_from_stdin)
  662.     {
  663.       int fd;
  664.       char *filename;
  665.       extern char *find_path_file ();
  666.       extern int errno;
  667.  
  668.       free (dollar_vars[0]);
  669.       dollar_vars[0] = savestring (argv[arg_index]);
  670.       filename = savestring (argv[arg_index]);
  671.  
  672.       fd = open (filename, O_RDONLY);
  673.       if ((fd < 0) && (errno == ENOENT))
  674.     {
  675.       char *path_filename;
  676.       /* If it's not in the current directory, try looking through PATH
  677.          for it. */
  678.       path_filename = find_path_file (argv[arg_index]);
  679.       if (path_filename)
  680.         {
  681.           free (filename);
  682.           filename = path_filename;
  683.           fd = open (filename, O_RDONLY);
  684.         }
  685.     }
  686.  
  687.       arg_index++;
  688.       if (fd < 0)
  689.     {
  690.       file_error (filename);
  691.       exit (1);
  692.     }
  693.  
  694.       /* Only do this with file descriptors we can seek on. */
  695.       if (lseek (fd, 0L, 1) != -1)
  696.     {
  697.       unsigned char sample[80];
  698.       int sample_len;
  699.  
  700.       /* Check to see if the `file' in `bash file' is a binary file
  701.          according to the same tests done by execute_simple_command (),
  702.          and report an error and exit if it is. */
  703.       sample_len = read (fd, sample, sizeof (sample));
  704.       if (sample_len > 0)
  705.         if (check_binary_file (sample, sample_len))
  706.           {
  707.         report_error ("%s: cannot execute binary file", filename);
  708.         exit (EX_BINARY_FILE);
  709.           }
  710.       /* Now rewind the file back to the beginning. */
  711.       lseek (fd, 0L, 0);
  712.     }
  713.  
  714.       default_input = fdopen (fd, "r");
  715.  
  716.       if (!default_input)
  717.     {
  718.       file_error (filename);
  719.       exit (127);
  720.     }
  721.  
  722.       SET_CLOSE_ON_EXEC (fd);
  723.       if (fileno (default_input) != fd)
  724.     SET_CLOSE_ON_EXEC (fileno (default_input));
  725.  
  726.       if (!interactive || (!isatty (fd)))
  727.     {
  728.       extern int history_expansion;
  729.       history_expansion = interactive = remember_on_history = 0;
  730. #ifdef JOB_CONTROL
  731.       set_job_control (0);
  732. #endif
  733.     }
  734.       else
  735.     {
  736.       /* I don't believe that this code is ever executed, even in
  737.          the presence of /dev/fd. */
  738.       dup2 (fd, 0);
  739.       close (fd);
  740.       fclose (default_input);
  741.     }
  742.     }
  743.  
  744.   /* Bind remaining args to $1 ... $n */
  745.   {
  746.     WORD_LIST *args = (WORD_LIST *)NULL;
  747.     while (arg_index != argc)
  748.       args = make_word_list (make_word (argv[arg_index++]), args);
  749.     args = (WORD_LIST *)reverse_list (args);
  750.     remember_args (args, 1);
  751.     dispose_words (args);
  752.   }
  753.  
  754.   unset_nodelay_mode (fileno (stdin));
  755.  
  756.   /* with_input_from_stdin really means `with_input_from_readline' */
  757.   if (interactive && !no_line_editing)
  758.     with_input_from_stdin ();
  759.   else
  760.     with_input_from_stream (default_input, dollar_vars[0]);
  761.  
  762.  read_and_execute:
  763.  
  764.   shell_initialized = 1;
  765.  
  766.   /* Read commands until exit condition. */
  767.   reader_loop ();
  768.  
  769.   /* Do trap[0] if defined. */
  770.   run_exit_trap ();
  771.  
  772.   maybe_save_shell_history ();
  773.  
  774. #if defined (JOB_CONTROL)
  775.   if (interactive && job_control)
  776.     give_terminal_to (original_pgrp);
  777. #endif /* JOB_CONTROL */
  778.  
  779.   /* Always return the exit status of the last command to our parent. */
  780.   exit (last_command_exit_value);
  781. }
  782.  
  783. /* If this is an interactive shell, then append the lines executed
  784.    this session to the history file. */
  785. int
  786. maybe_save_shell_history ()
  787. {
  788.   int result = 0;
  789.  
  790.   if (interactive && history_lines_this_session)
  791.     {
  792.       void using_history ();
  793.       char *hf = get_string_value ("HISTFILE");
  794.  
  795.       if (hf)
  796.     {
  797.       struct stat buf;
  798.  
  799.       /* If the file doesn't exist, then create it. */
  800.       if (stat (hf, &buf) == -1)
  801.         {
  802.           int file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
  803.           if (file != -1)
  804.         close (file);
  805.         }
  806.  
  807.       /* Now actually append the lines if the history hasn't been
  808.          stifled. */
  809.       using_history ();
  810.       if (history_lines_this_session <= where_history ())
  811.         {
  812.           result = append_history (history_lines_this_session, hf);
  813.           history_lines_in_file += history_lines_this_session;
  814.           history_lines_this_session = 0;
  815.         }
  816.     }
  817.     }
  818.   return (result);
  819. }
  820.  
  821. /* Try to execute the contents of FNAME.  If FNAME doesn't exist,
  822.    that is not an error, but other kinds of errors are.  Returns
  823.    -1 in the case of an error, 0 in the case that the file was not
  824.    found, and 1 if the file was found and executed. */
  825. maybe_execute_file (fname)
  826.      char *fname;
  827. {
  828.   extern int errno;
  829.   char *tilde_expand ();
  830.   char *filename = tilde_expand (fname);
  831.  
  832.   struct stat file_info;
  833.  
  834.   int tt, tresult;
  835.   char *string;
  836.   int fd = open (filename, O_RDONLY);
  837.  
  838.   if (fd < 0)
  839.     {
  840. file_error_and_exit:
  841.       if (errno != ENOENT)
  842.     file_error (filename);
  843.       free (filename);
  844.       return ((errno == ENOENT) ? 0 : -1);
  845.     }
  846.  
  847.   if (fstat (fd, &file_info) == -1)
  848.     goto file_error_and_exit;
  849.  
  850.   string = (char *)xmalloc (1 + file_info.st_size);
  851.   tresult = read (fd, string, file_info.st_size);
  852.   tt = errno;
  853.   close (fd);
  854.   errno = tt;
  855.   if (tresult != file_info.st_size)
  856.     {
  857.       free (string);
  858.       goto file_error_and_exit;
  859.     }
  860.   string[file_info.st_size] = '\0';
  861.  
  862.   parse_and_execute (string, filename);
  863.   free (filename);
  864.  
  865.   return (1);
  866. }
  867.  
  868. reader_loop ()
  869. {
  870.   extern int indirection_level;
  871.   int our_indirection_level;
  872.   COMMAND *current_command = (COMMAND *)NULL;
  873.  
  874.   our_indirection_level = ++indirection_level;
  875.  
  876.   while (!EOF_Reached)
  877.     {
  878.       sighandler sigint_sighandler ();
  879.       int code = setjmp (top_level);
  880.       extern char *trap_list[];
  881.  
  882.       signal (SIGINT, sigint_sighandler);
  883.  
  884.       if (code != NOT_JUMPED)
  885.     {
  886.       indirection_level = our_indirection_level;
  887.  
  888.       switch (code)
  889.         {
  890.           /* Some kind of throw to top_level has occured. */
  891.         case FORCE_EOF:
  892.         case EXITPROG:
  893.           current_command = (COMMAND *)NULL;
  894.           EOF_Reached = EOF;
  895.           goto exec_done;
  896.  
  897.         case DISCARD:
  898.           /* Obstack free command elements, etc. */
  899.           break;
  900.  
  901.         default:
  902.           programming_error ("Bad jump %d", code);
  903.         }
  904.     }
  905.  
  906.       executing = 0;
  907.       dispose_used_env_vars ();
  908.  
  909.       if (read_command () == 0)
  910.     {
  911.       if (global_command) {
  912.         current_command = global_command;
  913.  
  914.         current_command_number++;
  915.  
  916.         /* POSIX spec: "-n    The shell reads commands but does
  917.            not execute them; this can be used to check for shell
  918.            script syntax errors.  The shell ignores the -n option
  919.            for interactive shells. " */
  920.  
  921.         if (interactive || !read_but_dont_execute)
  922.           {
  923.         executing = 1;
  924.         execute_command (current_command);
  925.               }
  926.  
  927.       exec_done:
  928.         if (current_command)
  929.           dispose_command (current_command);
  930.         QUIT;
  931.       }
  932.     }
  933.       else
  934.     {
  935.       /* Parse error, maybe discard rest of stream if not interactive. */
  936.       if (!interactive)
  937.         EOF_Reached = EOF;
  938.     }
  939.       if (just_one_command)
  940.     EOF_Reached = EOF;
  941.     }
  942.   indirection_level--;
  943. }
  944.  
  945. /* Return a string denoting what our indirection level is. */
  946. static char indirection_string[100];
  947.  
  948. char *
  949. indirection_level_string ()
  950. {
  951.   register int i, j;
  952.   char *get_string_value (), *ps4 = get_string_value ("PS4");
  953.   extern char *decode_prompt_string ();
  954.  
  955.   if (!ps4)
  956.     ps4 = savestring ("+ ");
  957.   else
  958.     ps4 = decode_prompt_string (ps4);
  959.  
  960.   for (i = 0; i < indirection_level && i < 99; i++)
  961.     indirection_string[i] = *ps4;
  962.  
  963.   for (j = 1; ps4[j] && i < 99; i++, j++)
  964.     indirection_string[i] = ps4[j];
  965.  
  966.   indirection_string[i] = '\0';
  967.   free (ps4);
  968.   return (indirection_string);
  969. }
  970.  
  971. static sighandler 
  972. alrm_catcher(i)
  973.      int i;
  974. {
  975.   printf ("%ctimed out waiting for input: auto-logout\n", '\07');
  976.   longjmp (top_level, EXITPROG);
  977. #ifdef ibm032
  978.   return (0);    /* To shut up the compiler */
  979. #endif
  980. }
  981.  
  982. parse_command ()
  983. {
  984.   extern int need_here_doc;
  985.   extern REDIRECT *redirection_needing_here_doc;
  986.   int r;
  987.   
  988.   need_here_doc = 0;
  989.   redirection_needing_here_doc = (REDIRECT *)NULL;
  990.  
  991.   run_pending_traps ();
  992.  
  993.   r = yyparse ();
  994.  
  995.   if (need_here_doc)
  996.     make_here_document (redirection_needing_here_doc);
  997.   need_here_doc = 0;
  998.  
  999.   return r;
  1000. }
  1001.  
  1002. read_command ()
  1003. {
  1004.   extern char *ps1_prompt, **prompt_string_pointer;
  1005.   SHELL_VAR *tmout_var = (SHELL_VAR *)NULL;
  1006.   int tmout_len = 0, result;
  1007.   SigHandler *old_alrm;
  1008.  
  1009.   prompt_string_pointer = &ps1_prompt;
  1010.   global_command = (COMMAND *)NULL;
  1011.  
  1012.   /* Only do timeouts if interactive. */
  1013.   if (interactive)
  1014.     {
  1015. /**
  1016.  ** (sjk)++ There is no nead to do an interative timeout on the Atari ST
  1017.  **/
  1018. #if !defined(atarist)
  1019.      tmout_var = find_variable ("TMOUT");
  1020.  
  1021.       if (tmout_var && tmout_var->value)
  1022.     {
  1023.       tmout_len = atoi (tmout_var->value);
  1024.       if (tmout_len > 0)
  1025.         {
  1026.           old_alrm = signal (SIGALRM, alrm_catcher);
  1027.           alarm (tmout_len);
  1028.         }
  1029.     }
  1030. #endif
  1031.     }
  1032.  
  1033.   QUIT;
  1034.  
  1035.   result = parse_command ();
  1036.  
  1037. /**
  1038.  ** (sjk)++ There is no need for an interactive timeout on the Atari ST
  1039.  **/
  1040. #if !defined(atarist)
  1041.   if (interactive && tmout_var && (tmout_len > 0))
  1042.     {
  1043.       alarm(0);
  1044.       signal (SIGALRM, old_alrm);
  1045.     }
  1046. #endif
  1047.   return (result);
  1048. }
  1049.  
  1050. /* Do whatever is necessary to initialize the shell.
  1051.    Put new initializations in here. */
  1052. shell_initialize ()
  1053. {
  1054.   /* Line buffer output for stderr.
  1055.      If your machine doesn't have either of setlinebuf or setvbuf,
  1056.      you can just comment out the buffering commands, and the shell
  1057.      will still work.  It will take more cycles, though. */
  1058. #if defined (HAVE_SETLINEBUF)
  1059.   setlinebuf (stderr);
  1060.   setlinebuf (stdout);
  1061. #else
  1062. # if defined (_IOLBF)
  1063.   setvbuf (stderr, (char *)NULL, _IOLBF, BUFSIZ);
  1064.   setvbuf (stdout, (char *)NULL, _IOLBF, BUFSIZ);
  1065. # endif
  1066. #endif /* HAVE_SETLINEBUF */
  1067.  
  1068.   /* Initialize the trap signal handlers before installing our own
  1069.      signal handlers.  traps.c:restore_default_signal () is responsible
  1070.      for restoring the original default signal handler.  That function
  1071.      is called from jobs.c when we make a new child. */
  1072.   initialize_traps ();
  1073.   initialize_signals ();
  1074.  
  1075.   /* Initialize current_user_name and current_host_name. */
  1076.   {
  1077.     struct passwd *entry = getpwuid (getuid ());
  1078.     char hostname[256];
  1079.  
  1080.     if (gethostname (hostname, 255) < 0)
  1081.       current_host_name = "??host??";
  1082.     else
  1083.       current_host_name = savestring (hostname);
  1084.  
  1085.     if (entry)
  1086.       current_user_name = savestring (entry->pw_name);
  1087.     else
  1088.       current_user_name = savestring ("I have no name!");
  1089.     endpwent ();
  1090.   }
  1091.  
  1092.   initialize_shell_variables (shell_environment);
  1093.   initialize_filename_hashing ();
  1094.   initialize_jobs ();
  1095. }
  1096.  
  1097. /* Function called by main () when it appears that the shell has already
  1098.    had some initialization preformed.  This is supposed to reset the world
  1099.    back to a pristine state, as if we had been exec'ed. */
  1100. shell_reinitialize ()
  1101. {
  1102.   extern int line_number, last_command_exit_value;
  1103.  
  1104.   /* The default shell prompts. */
  1105.   primary_prompt = PPROMPT;
  1106.   secondary_prompt = SPROMPT;
  1107.  
  1108.   /* Things that get 1. */
  1109.   current_command_number = 1;
  1110.  
  1111.   /* We have decided that the ~/.bashrc file should not be executed
  1112.      for the invocation of each shell script.  Perhaps some other file
  1113.      should.  */
  1114.   act_like_sh = 1;
  1115.  
  1116.   /* Things that get 0. */
  1117.   login_shell = make_login_shell = interactive = restricted = executing = 0;
  1118.   debugging = no_rc = no_profile = do_version = line_number = 0;
  1119.   last_command_exit_value = remember_on_history = 0;
  1120.   forced_interactive = interactive_shell = 0;
  1121.  
  1122.   /* Ensure that the default startup file is used.  (Except that we don't
  1123.      execute this file for reinitialized shells). */
  1124.   bashrc_file = "~/.bashrc";
  1125.  
  1126.   /* Delete all variables and functions.  They will be reinitialized when
  1127.      the environment is parsed. */
  1128.  
  1129.   delete_all_variables (shell_variables);
  1130.   delete_all_variables (shell_functions);
  1131.   
  1132.   /* Pretend the PATH variable has changed. */
  1133.   sv_path ("PATH");
  1134. }
  1135.  
  1136. initialize_signals ()
  1137. {
  1138.   initialize_terminating_signals ();
  1139.   initialize_job_signals ();
  1140. #if defined (INITIALIZE_SIGLIST)
  1141.   initialize_siglist ();
  1142. #endif
  1143. }
  1144.  
  1145. /* The list of signals that would terminate the shell if not caught.
  1146.    We catch them, but just so that we can write the history file,
  1147.    and so forth. */
  1148. int terminating_signals[] = {
  1149. #ifdef SIGHUP
  1150.   SIGHUP,
  1151. #endif
  1152.  
  1153. #ifdef SIGINT
  1154.   SIGINT,
  1155. #endif
  1156.  
  1157. #ifdef SIGQUIT
  1158.   SIGQUIT,
  1159. #endif
  1160.  
  1161. #ifdef SIGILL
  1162.   SIGILL,
  1163. #endif
  1164.  
  1165. #ifdef SIGTRAP
  1166.   SIGTRAP,
  1167. #endif
  1168.  
  1169. #ifdef SIGIOT
  1170.   SIGIOT,
  1171. #endif
  1172.  
  1173. #ifdef SIGDANGER
  1174.   SIGDANGER,
  1175. #endif
  1176.  
  1177. #ifdef SIGEMT
  1178.   SIGEMT,
  1179. #endif
  1180.  
  1181. #ifdef SIGFPE
  1182.   SIGFPE,
  1183. #endif
  1184.  
  1185.  
  1186. #ifdef SIGKILL
  1187.   SIGKILL,
  1188. #endif
  1189.  
  1190.  
  1191. #ifdef SIGBUS
  1192.   SIGBUS,
  1193. #endif
  1194.  
  1195.  
  1196. #ifdef SIGSEGV
  1197.   SIGSEGV,
  1198. #endif
  1199.  
  1200. #ifdef SIGSYS
  1201.   SIGSYS,
  1202. #endif
  1203.  
  1204. #ifdef SIGPIPE
  1205.   SIGPIPE,
  1206. #endif
  1207.  
  1208. #ifdef SIGALRM
  1209.   SIGALRM,
  1210. #endif
  1211.  
  1212. #ifdef SIGTERM
  1213.   SIGTERM,
  1214. #endif
  1215.  
  1216. #ifdef SIGXCPU
  1217.   SIGXCPU,
  1218. #endif
  1219. #ifdef SIGXFSZ
  1220.   SIGXFSZ,
  1221. #endif
  1222. #ifdef SIGVTALRM
  1223.   SIGVTALRM,
  1224. #endif
  1225. #ifdef SIGPROF
  1226.   SIGPROF,
  1227. #endif
  1228. #ifdef SIGLOST
  1229.   SIGLOST,
  1230. #endif
  1231. #ifdef SIGUSR1
  1232.   SIGUSR1, SIGUSR2
  1233. #endif
  1234.     };
  1235.  
  1236. #define TERMSIGS_LENGTH (sizeof (terminating_signals) / sizeof (int))
  1237.  
  1238. /* This function belongs here? */
  1239. sighandler
  1240. termination_unwind_protect (sig)
  1241.      int sig;
  1242. {
  1243.   maybe_save_shell_history ();
  1244.   signal (sig, SIG_DFL);
  1245.   kill (getpid (), sig);
  1246. #ifdef ibm032
  1247.   return (0);    /* To shut up the compiler */
  1248. #endif
  1249. }
  1250.  
  1251. /* Initialize signals that will terminate the shell to do some
  1252.    unwind protection. */
  1253. initialize_terminating_signals ()
  1254. {
  1255.   register int i;
  1256.  
  1257. #if defined (_POSIX_VERSION)
  1258.   /* If we're running on a Posix-compliant system, do things the Posix way. */
  1259.  
  1260.   struct sigaction act;
  1261.  
  1262.   act.sa_handler = termination_unwind_protect;
  1263.   act.sa_flags = 0;
  1264.   sigemptyset (&act.sa_mask);
  1265.   for (i = 0; i < TERMSIGS_LENGTH; i++)
  1266.     sigaddset (&act.sa_mask, terminating_signals[i]);
  1267.   for (i = 0; i < TERMSIGS_LENGTH; i++)
  1268.     sigaction (terminating_signals[i], &act, (struct sigaction *)NULL);
  1269.  
  1270.   /* Clear signal mask for interactive login shell. */
  1271.   if (login_shell)
  1272.     {
  1273.       sigset_t set;
  1274.  
  1275.       sigemptyset (&set);
  1276.       sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
  1277.     }
  1278.  
  1279. #else /* _POSIX_VERSION */
  1280.  
  1281.   for (i = 0; i < TERMSIGS_LENGTH; i++)
  1282.     signal (terminating_signals[i], termination_unwind_protect);
  1283.  
  1284. #endif /* _POSIX_VERSION */
  1285.  
  1286.   /* And, some signals that are specifically ignored by the shell. */
  1287.   signal (SIGQUIT, SIG_IGN);
  1288.  
  1289.   if (login_shell)
  1290.     signal (SIGTERM, SIG_IGN);
  1291. }
  1292.  
  1293. /* What to do when we've been interrupted, and it is safe to handle it. */
  1294. sighandler
  1295. throw_to_top_level ()
  1296. {
  1297.   extern int last_command_exit_value, loop_level, continuing, breaking;
  1298.   extern int return_catch_flag;
  1299.   extern int special_source_interrupt; 
  1300.   int print_newline = 0;
  1301.  
  1302.   if (special_source_interrupt)
  1303.     {
  1304.       extern jmp_buf special_buf;
  1305.  
  1306.       longjmp (special_buf, 1);
  1307.     }
  1308.  
  1309.   if (interrupt_state)
  1310.     {
  1311.       print_newline = 1;
  1312.       interrupt_state--;
  1313.     }
  1314.  
  1315.   if (interrupt_state)
  1316.     return;
  1317.  
  1318. #if defined (JOB_CONTROL)
  1319.   give_terminal_to (shell_pgrp);
  1320. #endif /* JOB_CONTROL */
  1321.  
  1322.   run_unwind_protects ();
  1323.   loop_level = continuing = breaking = 0;
  1324.   return_catch_flag = 0;
  1325.  
  1326.   reset_parser ();
  1327.  
  1328.   if (interactive && print_newline)
  1329.     {
  1330.       fflush (stdout);
  1331.       fprintf (stderr, "\n");
  1332.     }
  1333.  
  1334. #if defined (READLINE)
  1335.   if (interactive)
  1336.     bashline_reinitialize ();
  1337. #endif /* READLINE */
  1338.  
  1339.   /* Run any traps set on interrupt. */
  1340.   run_interrupt_trap ();
  1341.  
  1342.   last_command_exit_value |= 128;
  1343.  
  1344.   if (interactive)
  1345.     longjmp (top_level, DISCARD);
  1346.   else
  1347.     longjmp (top_level, EXITPROG);
  1348. }
  1349.  
  1350. /* When non-zero, we throw_to_top_level (). */
  1351. int interrupt_immediately = 0;
  1352.  
  1353. /* What we really do when SIGINT occurs. */
  1354. sighandler
  1355. sigint_sighandler (sig)
  1356.      int sig;
  1357. {
  1358. /**
  1359.  **  (sjk)++ Offer up the signal ala USG on the Atari ST
  1360.  **/
  1361. #if (defined (USG) && !defined(_POSIX_VERSION)) || defined(atarist)
  1362.   signal (sig, sigint_sighandler);
  1363. #endif
  1364.  
  1365.   /* interrupt_state needs to be set for the stack of interrupts to work
  1366.      right.  Should it be set unconditionally? */
  1367.   if (!interrupt_state)
  1368.     interrupt_state++;
  1369.   if (interrupt_immediately)
  1370.     {
  1371.       interrupt_immediately = 0;
  1372.       throw_to_top_level ();
  1373.     }
  1374. #ifdef ibm032
  1375.   return (0);    /* To shut up the compiler */
  1376. #endif
  1377. }
  1378.     
  1379. /* Write the existing history out to the history file. */
  1380. save_history ()
  1381. {
  1382.   void using_history ();
  1383.  
  1384.   using_history ();
  1385.   write_history (get_string_value ("HISTFILE"));
  1386. }
  1387.  
  1388. #if defined (MAKE_BUG_REPORTS)
  1389. /* Make a bug report, even to the extent of mailing it.  Hope that it
  1390.    gets where it is supposed to go.  If not, maybe the user will send
  1391.    it back to me. */
  1392. #include <readline/history.h>
  1393. /* Number of commands to place in the bug report. */
  1394. #define LAST_INTERESTING_HISTORY_COUNT 6
  1395.  
  1396. #if defined (HAVE_VPRINTF)
  1397. make_bug_report (va_alist)
  1398.      va_dcl
  1399. #else
  1400. make_bug_report (reason, arg1, arg2)
  1401.      char *reason;
  1402. #endif /* HAVE_VPRINTF */
  1403. {
  1404.   extern char *current_host_name, *current_user_name, *the_current_maintainer;
  1405.   extern int interactive, login_shell;
  1406.   register int len = where_history ();
  1407.   register int i = len - LAST_INTERESTING_HISTORY_COUNT;
  1408.   FILE *stream, *popen ();
  1409.   HIST_ENTRY **list = history_list ();
  1410.  
  1411. #if defined (HAVE_VPRINTF)
  1412.   char *reason;
  1413.   va_list args;
  1414. #endif /* HAVE_VPRINTF */
  1415.  
  1416.   stream = popen ("/bin/rmail bash-maintainers@ai.mit.edu", "w");
  1417.  
  1418.   save_history ();
  1419.   if (i < 0) i = 0;
  1420.  
  1421.   if (stream)
  1422.     {
  1423.       fprintf (stream, "To: bash-maintainers@ai.mit.edu\n");
  1424.       fprintf (stream, "Subject: Bash-%s.%d bug-report: ",
  1425.            dist_version, build_version);
  1426.  
  1427. #if defined (HAVE_VPRINTF)
  1428.       va_start (args);
  1429.       reason = va_arg (args, char *);
  1430.       vfprintf (stream, reason, args);
  1431.       va_end (args);
  1432. #else
  1433.       fprintf (stream, reason, arg1, arg2);
  1434. #endif                /* HAVE_VPRINTF */
  1435.  
  1436.       fprintf (stream, "\n");
  1437.  
  1438.       /* Write the history into the mail file.  Maybe we can recreate
  1439.      the bug? */
  1440.       fprintf (stream,
  1441.            "This is a Bash bug report.  Bash maintainers should be getting this report.\n\
  1442. If this mail has bounced, for right now please send it to:\n\
  1443. \n\
  1444.     %s\n\
  1445. \n\
  1446. since he is the current maintainer of this version of the shell.\n\
  1447. \n\
  1448. This is %s (invoked as `%s'), version %s.%d, on host %s, used by %s.\n\
  1449. This shell is %sinteractive, and it is %sa login shell.\n\
  1450. \n\
  1451. The host is a %s running %s.\n\
  1452. \n\
  1453. The current environment is:\n",
  1454.            the_current_maintainer,
  1455.            get_string_value ("BASH"), full_pathname (dollar_vars[0]),
  1456.            dist_version, build_version, current_host_name,
  1457.            current_user_name, interactive ? "" : "not ",
  1458.            login_shell ? "" : "not ", SYSTEM_NAME, OS_NAME);
  1459.  
  1460.       {
  1461.     SHELL_VAR **vlist, *var;
  1462.     register int i;
  1463.  
  1464.     vlist = all_shell_variables ();
  1465.  
  1466.     for (i = 0; vlist && var = vlist[i]; i++)
  1467.       {
  1468.         if (!invisible_p (var) && exported_p (var))
  1469.           {
  1470.         fprintf (stream, "%s=%s", var->name, value_cell (var));
  1471.         fprintf (stream, "\n");
  1472.           }
  1473.       }
  1474.       }
  1475.  
  1476.       fprintf (stream, "\nAnd here are the last %d commands.\n\n",
  1477.            LAST_INTERESTING_HISTORY_COUNT);
  1478.  
  1479.       for (; i < len; i++)
  1480.     fprintf (stream, "%s\n", list[i]->line);
  1481.  
  1482.       pclose (stream);
  1483.     }
  1484.   else
  1485.     {
  1486.       fprintf (stderr, "Can't mail bug report!\n");
  1487.     }
  1488. }
  1489. #endif /* MAKE_BUG_REPORTS */
  1490.  
  1491. /* Give version information about this shell. */
  1492. show_shell_version ()
  1493. {
  1494.   extern char *shell_name;
  1495.   extern int version;
  1496.  
  1497.   printf ("GNU %s, version %s.%d\n", base_pathname (shell_name),
  1498.       dist_version, build_version);
  1499. }
  1500.